part of '../writer.dart';

/// 通过文件读写方式实现了Writer接口
/// 由于数据是通过字符串的方式写入文件，因此需要提供序列化与反序列化的方法
class FileWriterRawable<T extends Jsonable> implements RawableWriter<T> {
  final File file;
  final T Function(Json raw) unzip;

  FileWriterRawable({
    required this.file,
    required this.unzip,
  });

  @override
  void input(T object) {
    // 将当前所有对象深拷贝一份，加入对象后储存
    List<T> deepCopy = List.from(all);
    deepCopy.add(object);
    file.write(deepCopy);
  }

  @override
  List<T> get all {
    // 如果文件不存在，则返回空列表
    if (!file.existsSync()) return [];
    // 读取文件字符串，并将它jsonList化
    JsonList rawList = jsonDecode(file.readAsStringSync());
    // 将List中的每一项映射为对象，并返回最终List
    List<T> unzipList = rawList.map((raw) => unzip(raw)).toList();
    return unzipList;
  }

  @override
  bool deleteBy(Test<T> test) {
    // 将列表深拷贝一份
    List<T> deepCopy = List.from(all);
    // 找到符合test的index
    int index = deepCopy.indexWhere(test);
    // 如果没有找到，则直接返回false
    if (index == -1) return false;
    // 如果找到了，则删除对应的对象后覆写文件，并返回true
    deepCopy.removeAt(index);
    file.write(deepCopy);
    return true;
  }

  @override
  T? findBy(Test<T> test) {
    // 在所有项中寻找符合test的对象
    int index = all.indexWhere(test);
    return index == -1 ? null : all[index];
  }

  @override
  T getBy(Test<T> test) {
    // 尝试寻找对象，如果没找到，则报错
    final T? object = findBy(test);
    if (object == null) throw Bug("没有根据测试函数找到对象");
    // 否则返回已找到的对象
    return object;
  }

  @override
  void deletAll() => file.deleteIf();
}
